Repository navigation
Write item name and quantity changes to an edited dfs file - #79
Draft
ryan-kipawa wants to merge 3 commits into
Draft
ryan-kipawa wants to merge 3 commits into
ryan-kipawa wants to merge 3 commits into
Conversation
Port the commented-out C# test of ExamplesDfs2.ModifyDfs2ItemInfo, the example from issue #38, and test name and quantity edits on every dfs file type and way of opening it for editing. They fail on master, which never writes item info. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DfsuFile.Flush passed itself to DfsFile.Flush, which takes no argument, so it raised TypeError. DfsuFileOpenAppend was the only Open method that required parameters. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In a file opened for editing, the file remembers the dynamic items it read. Flush and Close write the ones whose Name changed or that were assigned a new Quantity, through dfsUpdateItemInfo. As in the C# library, a new name is truncated or padded to the stored length, and a Quantity changed in place is not written. Every change is checked before any is written, and Close still closes the file when it raises. Closes #38 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #38
What and why
In a dfs file opened for editing, assigning
ItemInfo[0].NameorItemInfo[0].Quantitychanged only the Python object, and closing the file wrote nothing. Fixing a wrong eumItem/eumUnit on a 100 GB file meant rewriting the file or using DataUtility. The C# library writes these item edits; the Python port never did.The file now writes these edits on
FlushorClose. When a file is opened in Edit or Append mode, it remembers the dynamic items it read and theQuantityobject each was read with. OnFlushorCloseit writes, throughdfsUpdateItemInfo, every item whoseNamechanged or that was assigned a newQuantity. Only the header changes; the data is never rewritten. The example from the issue (ExamplesDfs2.ModifyDfs2ItemInfo) now works unchanged.The C# library behaves the same way in these respects:
Quantity.ItemorQuantity.Unitin place is not written; only assigning a newQuantityis.Errors:
UnicodeEncodeError.ValueError.eumItemUnitEqv) raisesValueError.Every change is checked before any is written, so a rejected value leaves the file unchanged, and
Closestill closes the file when it raises.Redesign. Earlier versions of this PR ported the C# change events: the setters and a
__setattr__override on axes wrote on assignment, and axis editing was included. That needed weak callbacks, rollback, copy handling and detaching items onClose, and most review rounds fixed a new aliasing or lifetime bug in that machinery. An adversarial design review found one more: acopy.copyof an item still wrote to the file. This version replaces all of that with one write atFlush/Close, and cuts the scope to what the issue asked for. The history was rebuilt from master; the old commits are still visible in this PR's timeline.Side finding:
DfsuFile.Flush()raisedTypeError(it passed itself toDfsFile.Flush), andDfsuFileOpenAppendwas the onlyOpenmethod that requiredparameters.Commits
da1afa6Test writing item name and quantity edits to a dfs file. This ports the commented-out C# test that runs the issue's example (test_ModifyLanduseItemInfoTest) and addstests/test_dfs_edit.py. Fails on master.b997d60FixDfsuFile.Flushand letDfsuFileOpenAppenddefault its parameters.237d24fWrite item name and quantity edits onFlushandClose, with a changelog entry.Changes
mikecore/DfsFile.py:Openrecords the dynamic items of an Edit/Append file.__WriteItemInfochecks every change, then writes the changes.Flushcalls it.Closecalls it in atry/finallyand then forgets the items, because their pointers point into the freed header.DfsDLLUtil.GetItemNameBytesreads the stored name bytes. A name that cp1252 cannot decode is written back unchanged when only theQuantitychanges.mikecore/DfsDLL.py: ctypes signature ofdfsUpdateItemInfo.mikecore/DfsuFile.py,mikecore/DfsFileFactory.py: the side finding.Not changed (on purpose)
Dfs123File.SpatialAxis): not written, as on master. The issue did not ask for this.test_ModifyAxisTeststays commented out.DfsBuilder: item edits are not written.Projection,FileInfoand the other item fields (reference coordinates, orientation and so on): not written.Things to know
dfsFileFlushdoes not write the header, so an edit reaches the file only onClose. This also applies to the time step count, and was already the case. Edit mode writes onFlush. Both docstrings and the changelog say so.Flush/Close, not on assignment. CallFlushto check beforeClose.dfsUpdateItemInfoitself failed partway through, the items before it would be written.Closewrites its edits when__del__runs;Flushtest reads the file's raw bytes while it is open, which is not yet tested on Windows (CI will be the first run).Evidence
Each claim is checked by a test that reads the file back after the edit:
tests/test_dfs2.py::Dfs2Tests::test_ModifyLanduseItemInfoTesttest_name_edit_is_written_to_that_item_only,test_quantity_edit_is_written_to_that_item_only(15 cases each)test_name_keeps_its_length_in_the_file(25)FlushandClose, the valid edit of another item is not written either, the file is byte-identical and is closedtest_rejected_value_changes_no_item(30)Close, for an in-placeQuantitychange, or for an item put intoItemInfotest_read_mode_writes_nothing,test_edit_after_close_writes_nothing,test_quantity_changed_in_place_is_not_written,test_item_put_in_item_info_is_not_writtenFlushwrites in Edit mode, and an append afterFlushlands at the endtest_flush_writes_the_edit_in_edit_mode,test_flush_then_appendQuantityedit keeps a name cp1252 cannot decode byte-identicaltest_quantity_edit_keeps_a_name_cp1252_cannot_decodeI checked that the tests catch a broken implementation by breaking one part at a time and running
tests/test_dfs_edit.py:test_rejected_value_changes_no_itemtry/finallyinClosetest_rejected_value_changes_no_itemItemInfoinstead of the items readtest_name_keeps_its_length_in_the_filetest_quantity_changed_in_place_is_not_writtenFlushdoesn't writetest_flush_writes_the_edit_in_edit_mode,test_rejected_value_changes_no_itemFull suite at each commit (
uv run pytest):At
237d24f:uvx pre-commit run --all-files: all passed.uv run pyrefly check: 0 errors, 328 warnings, the same as master; the CI cap is 330.🤖 Generated with Claude Code